<template>
  <div>
    地址:
    <el-input v-model="value" placeholder="请输入地址" clearable style="width:170px" />
    <el-button style="margin-left: 20px;" type="primary" icon="el-icon-search" size="small" @click="onSearch">搜索
    </el-button>
    <!-- <el-button style="margin-left: 20px;" type="primary" icon="el-icon-success" size="small" @click="handleClick">确 定
    </el-button> -->
    <div :id="tid" class="map-content"></div>
    <h4>
      地址: {{ address.name }} 详细地址: {{ address.detail }} 经度: {{ address.longitude }} 纬度: {{ address.latitude }}
    </h4>
  </div>
</template>

<script>

export default {
  name: 'TFMap',
  props: {
    /**
     * 经度
     */
    longitude: {
      type: Number,
      required: true,
    },
    /**
     * 纬度
     */
    latitude: {
      type: Number,
      required: true,
    },
    currentAddress: {
      type: String,
      default: ''
    },
    tid: {
      type: String,
      default: 'map'
    }
  },
  data () {
    return {
      initCoordinates: [118.851360671567, 31.7807297960033],
      map: null,
      marker: null,
      popup: null,
      sfCodingQuery: null,
      sfRGeoCodingQuery: null,
      value: "",
      show: false,
      // 地址信息
      address: {
        name: "",
        detail: "",
        longitude: 0,
        latitude: 0,
      }
    };
  },
  mounted () {
    // 挂载完成后渲染地图
    this.loadScripts();
  },
  created () {
  },
  watch: {
    mapAndlngLat: {
      handler (newVal) {
        const { map, longitude, latitude, currentAddress, sfRGeoCodingQuery } = newVal || {};
        if (longitude) {
          this.address = {
            name: currentAddress,
            detail: currentAddress,
            longitude: longitude,
            latitude: latitude,
          }
        } else {
          this.address = {
            name: '',
            detail: '',
            longitude: 118.83414506997173,
            latitude: 31.954718562357378,
          }
        }
        if (map && longitude && latitude && sfRGeoCodingQuery) {
          this.getAddressByLngLat({
            x: longitude,
            y: latitude,
          })?.then(() => {
            this.setPonit([longitude, latitude]);
          });
        }
      },
      immediate: true,
    },
  },
  computed: {
    mapAndlngLat () {
      return {
        map: this.map,
        longitude: this.longitude,
        latitude: this.latitude,
        currentAddress: this.currentAddress,
        sfRGeoCodingQuery: this.sfRGeoCodingQuery,
      };
    },
  },

  methods: {
    loadScripts () {
      const wgs84_wgs84_mapcrs = {
        topTileExtent: [-180, -270, 180, 90],
        tileSize: 256,
      };

      // 构造地图对象实例,并添加到id为map的div容器中
      this.map = new window.GeoGlobe.Map({
        container: this.tid, //绑定容器
        mapCRS: wgs84_wgs84_mapcrs, //定义坐标系
        zoom: 13, //当前缩放级别
        center: this.initCoordinates, //定位中心点
        maxZoom: 20, //最大缩放级别
        minZoom: 10, //最小缩放级别
      });

      if (this.map) {
        this.map.on("load", () => {
          var wmts = new window.GeoGlobe.Format.WMTS();
          //加载注记
          let zj_url = "http://58.213.148.61:8089/geostar/JNTDT_ZJ/wmts";
          var zj_layer = wmts.createLayer(zj_url);
          //加载地图
          let dt_url = "http://58.213.148.61:8089/geostar/JNTDT_DT/wmts";
          var dt_layer = wmts.createLayer(dt_url);

          // 添加图层
          this.map.addLayer(dt_layer);
          this.map.addLayer(zj_layer);

          // 控制版
          const Na_control = new window.GeoGlobe.Control.Navigation();
          this.map.addControl(Na_control, "top-left");

          // 点击事件
          this.map.on("click", (e) => {
            this.getAddressByLngLat({
              x: e.lngLat?.lng,
              y: e?.lngLat?.lat,
            })?.then(() => {
              this.setPonit([e.lngLat?.lng, e?.lngLat?.lat]);
            });
          });
          //   搜索框
          this.sfCodingQuery = new window.GeoGlobe.Query.SFCodingQuery();
          // 逆地名地址查询实例
          this.sfRGeoCodingQuery =
            new window.GeoGlobe.Query.SFRGeoCodingQuery();
        });
      }
    },
    /**
     * @param {number} x longitude
     * @param {number} y latitude
     */
    getAddressByLngLat ({ x, y }) {
      return new Promise((resolve, reject) => {
        if (this.sfRGeoCodingQuery) {
          this.sfRGeoCodingQuery.query({ x, y }, (result) => {
            if (result.msg) {
              reject("没有查询到结果。");
            } else {
              const detail = result.name;
              const longitude = result.pois?.[0]?.x;
              const latitude = result.pois?.[0]?.y;
              this.show = true;
              //  TODO
              //  减少误差，如果误差过大，则不能认为是同一个位置（存疑，未验证）
              //  300米？
              if (
                Math.abs(longitude - result?.my_x) <= 0.003 &&
                Math.abs(latitude - result?.my_y) <= 0.003
              ) {
                this.address = {
                  name: result.pois?.[0]?.name,
                  detail,
                  longitude,
                  latitude,
                };
              } else {
                this.address = {
                  name: "",
                  detail,
                  longitude: result.my_x,
                  latitude: result.my_y,
                };
              }
              // 自动保存  
              this.handleClick();

              resolve(this.address);
            }
          });
        }
      });
    },
    startSearch (keyWord) {
      // 开始查询
      if (this.sfCodingQuery) {
        this.sfCodingQuery.query({ query: keyWord }, (data) => {
          let features = data.features;
          if (!features || !features?.[0]) {
            this.$toast.fail("未找到结果");
            return;
          }
          const val = features?.[0];

          this.show = true;
          this.address = {
            name: val?.properties?.name,
            detail: val?.properties?.address,
            longitude: val.properties.lonlat.lng,
            latitude: val?.properties?.lonlat?.lat,
          };

          this.setPonit([
            val.properties.lonlat.lng,
            val.properties.lonlat.lat,
          ]);
          // 自动保存  
          this.handleClick();
        });
      }
    },
    onSearch () {
      if (this.value) {
        this.startSearch(this.value);
      }
    },
    setPonit ([longitude, latitude]) {
      if (this.marker) {
        this.marker?.setLngLat([longitude, latitude]);
      } else {
        this.marker = new window.GeoGlobe.Marker()
          .setLngLat([longitude, latitude])
          .addTo(this.map); //添加mark到地图上
      }
      this.map.flyTo({
        center: [longitude, latitude],
        zoom: 13,
      });
    },
    handleClick () {
      this.$emit("click", {
        address: this.address.detail,
        coordinates: [this.address.longitude, this.address.latitude],
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.map-content {
  width: 100%;
  height: 400px;
  position: relative;
}

.header {
  width: 100%;
  height: 70px;
  background: #ffffff;
  padding: 16px 10px;
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
}

.search {
  border-radius: 20px;
  height: 40px;
  border: 1px solid rgba(0, 140, 240, 0.5);

  &:deep(.van-search__content, .van-cell) {
    background-color: #fff;
  }

  &:deep(.van-search__action) {
    padding-right: 6px;
  }

  &:deep(.van-search__action:active) {
    background-color: transparent;
    opacity: 0.8;
  }

  &-btn {
    width: 58px;
    height: 32px;
    background: #008cf0;
    border-radius: 16px;
    font-size: 14px;
    font-weight: 400;
    color: #ffffff;
  }
}

.popup {
  width: 100vw;
  height: 162px;
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
}

.footer {
  width: 100vw;
  height: 100%;
  padding: 25px 10px;
  align-items: flex-start;

  &-left {
    width: calc(100vw - 120px);
    margin-right: 20px;
    margin-top: 2px;
  }

  &-title {
    font-size: 20px;
    font-weight: 500;
    color: #333333;
    line-height: 28px;
    margin-top: 0;
    margin-bottom: 10px;
  }

  &-detail {
    height: 20px;
    font-size: 14px;
    font-weight: 400;
    color: #666666;
    margin-top: 0;
    line-height: 20px;
  }

  &-btn {
    width: 72px;
    background: linear-gradient(321deg, #0091ff 0%, #0079cf 100%);
    border-radius: 20px;
  }
}
</style>
